package com.xnx3.net;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.zip.GZIPInputStream;

public class AuthHttpUtil
{
  public static final String UTF8 = "UTF-8";
  public static final String GBK = "GBK";
  private String encode;
  private String cookies = "";
  private int timeout = 30000;

  public void setTimeout(int secend)
  {
    this.timeout = (secend * 1000);
  }

  public AuthHttpUtil()
  {
    this.encode = Charset.defaultCharset().name();
  }

  public AuthHttpUtil(String encode)
  {
    this.encode = encode;
  }

  public void setEncode(String encode)
  {
    this.encode = encode;
  }

  public String getCookies()
  {
    return this.cookies;
  }

  public void setCookies(String cookies)
  {
    this.cookies = cookies;
  }

  public HttpResponse get(String url)
    throws IOException
  {
    return send(url, "GET", null, null);
  }

  public HttpResponse get(String urlString, Map<String, String> params)
  {
    try
    {
      return send(urlString, "GET", params, null);
    }
    catch (IOException e) {
      e.printStackTrace();
    }return null;
  }

  public HttpResponse get(String urlString, Map<String, String> params, Map<String, String> propertys)
  {
    try
    {
      return send(urlString, "GET", params, propertys);
    }
    catch (IOException e) {
      e.printStackTrace();
    }return null;
  }

  public HttpResponse post(String urlString)
  {
    try
    {
      return send(urlString, "POST", null, null);
    }
    catch (IOException e) {
      e.printStackTrace();
    }return null;
  }

  public HttpResponse post(String urlString, Map<String, String> params)
    throws IOException
  {
    return send(urlString, "POST", params, null);
  }

  public HttpResponse post(String urlString, Map<String, String> params, Map<String, String> propertys)
  {
    try
    {
      return send(urlString, "POST", params, propertys);
    } catch (IOException e) {
      e.printStackTrace();
    }return null;
  }

  public static String mapToUrl(String url, Map<String, String> parameters)
  {
    int i = 0;
    if (url.indexOf("?") > 0) {
      i = 1;
    }

    StringBuffer param = new StringBuffer();

    for (String key : parameters.keySet()) {
      if (i == 0)
        param.append("?");
      else {
        param.append("&");
      }
      param.append(key).append("=").append((String)parameters.get(key));
      i++;
    }
    url = new StringBuilder().append(url).append(param).toString();
    return url;
  }

  public static String mapToQueryString(Map<String, String> parameters)
  {
    String data = "";
    StringBuffer param = new StringBuffer();
    int i;
    if (parameters != null) {
      i = 0;
      for (Map.Entry entry : parameters.entrySet()) {
        if (i > 0) {
          param.append("&");
        }
        param.append((String)entry.getKey()).append("=").append((String)entry.getValue());
        i++;
      }
    }
    if (param.length() > 0) {
      data = param.toString();
    }
    return data;
  }

  private HttpResponse send(String urlString, String method, Map<String, String> parameters, Map<String, String> propertys)
    throws IOException
  {
    HttpURLConnection urlConnection = null;

    if ((method.equalsIgnoreCase("GET")) && (parameters != null)) {
      urlString = mapToUrl(urlString, parameters);
    }

    URL url = new URL(urlString);
    urlConnection = (HttpURLConnection)url.openConnection();
    urlConnection.setRequestMethod(method);
    urlConnection.setDoOutput(true);
    urlConnection.setDoInput(true);
    urlConnection.setUseCaches(false);
    urlConnection.setRequestProperty("Cookie", this.cookies);
    Iterator localIterator;
    if (propertys != null)
      for (localIterator = propertys.keySet().iterator(); localIterator.hasNext(); ) {
    	  String key = (String)localIterator.next();
    	  urlConnection.addRequestProperty(key, (String)propertys.get(key));
      }
//    String key;
    if ((method.equalsIgnoreCase("POST")) && (parameters != null)) {
      StringBuffer param = new StringBuffer();
      for (String key : parameters.keySet()) {
        param.append("&");
        param.append(key).append("=").append((String)parameters.get(key));
      }
      urlConnection.getOutputStream().write(param.toString().getBytes());
      urlConnection.getOutputStream().flush();
      urlConnection.getOutputStream().close();
    }
    return makeContent(urlString, urlConnection);
  }

  public HttpResponse makeContent(String urlString, HttpURLConnection urlConnection)
    throws IOException
  {
    urlConnection.setConnectTimeout(this.timeout);
    urlConnection.setReadTimeout(this.timeout);
    HttpResponse httpResponser = new HttpResponse();
    try {
      InputStream in = urlConnection.getInputStream();
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
      httpResponser.contentCollection = new Vector();
      StringBuffer temp = new StringBuffer();
      String line = bufferedReader.readLine();
      while (line != null) {
        httpResponser.contentCollection.add(line);
        temp.append(line).append("\r\n");
        line = bufferedReader.readLine();
      }
      bufferedReader.close();
      String ecod = urlConnection.getContentEncoding();
      if (ecod == null)
        ecod = this.encode;
      httpResponser.urlString = urlString;

      if (((this.cookies == null) || (this.cookies.equals(""))) && 
        (urlConnection.getHeaderFields().get("Set-Cookie") != null)) {
        List listS = (List)urlConnection.getHeaderFields().get("Set-Cookie");
        String cookie = "";
        if (listS != null) {
          for (int i = 0; i < listS.size(); i++)
            cookie = new StringBuilder().append(cookie).append(cookie.equals("") ? "" : ", ").append((String)listS.get(i)).toString();
        }
        else {
          cookie = urlConnection.getHeaderField("Set-Cookie");
        }
        this.cookies = cookie;
        httpResponser.cookie = this.cookies;
      }

      httpResponser.defaultPort = urlConnection.getURL().getDefaultPort();
      httpResponser.file = urlConnection.getURL().getFile();
      httpResponser.host = urlConnection.getURL().getHost();
      httpResponser.path = urlConnection.getURL().getPath();
      httpResponser.port = urlConnection.getURL().getPort();
      httpResponser.protocol = urlConnection.getURL().getProtocol();
      httpResponser.query = urlConnection.getURL().getQuery();
      httpResponser.ref = urlConnection.getURL().getRef();
      httpResponser.userInfo = urlConnection.getURL().getUserInfo();
      httpResponser.content = new String(temp.toString().getBytes(), ecod);
      httpResponser.contentEncoding = ecod;
      httpResponser.code = urlConnection.getResponseCode();
      httpResponser.message = urlConnection.getResponseMessage();
      httpResponser.contentType = urlConnection.getContentType();
      httpResponser.method = urlConnection.getRequestMethod();
      httpResponser.connectTimeout = urlConnection.getConnectTimeout();
      httpResponser.readTimeout = urlConnection.getReadTimeout();
      httpResponser.headerFields = urlConnection.getHeaderFields();
    } catch (IOException e) {
      httpResponser.code = 404;
    } finally {
      if (urlConnection != null)
        urlConnection.disconnect();
    }
    return httpResponser;
  }

  public String uncompress(ByteArrayInputStream in, String charset)
  {
    try
    {
      GZIPInputStream gInputStream = new GZIPInputStream(in);
      byte[] by = new byte[1024];
      StringBuffer strBuffer = new StringBuffer();
      int len = 0;
      while ((len = gInputStream.read(by)) != -1) {
        strBuffer.append(new String(by, 0, len, charset));
      }
      return strBuffer.toString();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }

  public String getGZIP(String requestUrl)
  {
    String result = null;

    URL url = null;
    try
    {
      for (int i = 0; i < 1; i++) {
        url = new URL(requestUrl);
        byte[] bytes = new byte[10240000];
        int index = 0;
        InputStream is = url.openStream();
        int count = is.read(bytes, index, 102400);
        while (count != -1) {
          index += count;
          count = is.read(bytes, index, 1);
        }
        ByteArrayInputStream biArrayInputStream = new ByteArrayInputStream(bytes);
        result = uncompress(biArrayInputStream, this.encode);
      }
    } catch (MalformedURLException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }

    return result;
  }
}